using System;
using System.Collections.Generic;

using IBatisNet.Common;
using IBatisNet.DataMapper;

using log4net;

using GymManager.Exception;
using GymManager.Persistence.VO;

namespace GymManager.Persistence.DAO
{
    /// <summary>
    /// Class responsible by getting information from database about stock item sales
    /// </summary>
    public class StockItemSalesDAO
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(StockItemSalesDAO));

        /// <summary>
        /// Method responsible by adding a new stock item sales register to database
        /// </summary>
        /// <param name="StockItemSales">stock item sales information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void create(StockItemSales stockItemSalesVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Insert("StockItemSales.insert", stockItemSalesVO);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving stock item sales information", ex);
                throw new PersistenceException("Error while saving stock item sales information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by marking as paid the sales made by some student.
        /// </summary>
        /// <param name="IList">sales id list</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void updateSalesListAsPaid(IList<Int32> salesIdList)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // generate in clause element
                String inClause = String.Empty;
                foreach( Int32 salesId in salesIdList)
                {
                    inClause += salesId + ",";
                }
                inClause = "(" + inClause.Substring(0, inClause.Length - 1) + ")";

                // updating information about stock item sales
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Update("StockItemSales.updateSalesListAsPaid", inClause);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving stock item sales information", ex);
                throw new PersistenceException("Error while retrieving stock item sales information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by getting an stock item by its key
        /// </summary>
        /// <param name="Int32">stock item's key</param>
        /// <returns>StockItem - stock item value object</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public StockItem findByKey(Int32 key)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // stock item value object to be returned
            StockItem stockItemResult = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                stockItemResult = ibatisMapper.QueryForObject<StockItem>("StockItem.findByKey", key);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving stock item information", ex);
                throw new PersistenceException("Error while retrieving stock item information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return stockItemResult;
        }


        /// <summary>
        /// Method responsible by finding all stock items sailed which are sold to a specific 
        /// student in a given month
        /// </summary>
        /// <param name="Int32">student identifier</param>
        /// <param name="DateTime">month to be used as filter</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<StockItemSales> findStockItemSalesByStudentInAMonth(Int32 studentId, DateTime salesDate)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // stock item sales value object list to be returned
            IList<StockItemSales> stockItemSalesList = null;

            try
            {
                // building query parameters
                IDictionary<String, Object> filterDictionary = new Dictionary<String, Object>();
                filterDictionary.Add("StudentId", studentId); filterDictionary.Add("SalesDate", salesDate);

                ISqlMapper ibatisMapper = DAOManager.getInstance();
                stockItemSalesList = ibatisMapper.QueryForList<StockItemSales>("StockItemSales.findStockItemSalesByStudentInAMonth", filterDictionary);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving stock item sales information", ex);
                throw new PersistenceException("Error while retrieving stock sales information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return stockItemSalesList;
        }

        /// <summary>
        /// Method responsible by getting all pending sales associated to a given student.
        /// </summary>
        /// <param name="Int32">student identifier</param>
        /// <returns>IList - list of all sales matching with the criteria </returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<StockItemSales> findPendingsByStudent(Int32 studentId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of stock item sales
            IList<StockItemSales> stockItemSalesList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                stockItemSalesList = ibatisMapper.QueryForList<StockItemSales>("StockItemSales.findPendingsByStudent", studentId);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving stock item sales information", ex);
                throw new PersistenceException("Error while retrieving stock item sales information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return stockItemSalesList;
        }
     }
}
